// Copyright Gary Evans 2006-2007.

using System;
using System.Collections.Generic;
using System.Text;

using Taumuon.Jabuka.Physics;

namespace Taumuon.Jabuka.MainApp
{
    /// <summary>
    /// The original scene.
    /// </summary>
    [Scene("1. Original scene", "The scene used in earlier tutorials, does not use CollisionManager")]
    public class Scene1 : IScene
    {
        #region Object Lifetime

        /// <summary>
        /// Default Constructor
        /// </summary>
        public Scene1()
        {
            // Initialise the objects.
            ResetScene();
        }

        #endregion Object Lifetime

        #region IScene Implementation

        /// <summary>
        /// The list of objects that will be drawn.
        /// </summary>
        public List<IDrawable> DrawableObjects
        {
            get
            {
                return this.drawableObjects;
            }
        }

        /// <summary>
        /// Resets the Scene to its starting point.
        /// </summary>
        public void ResetScene()
        {
            Vector initialAxesLocation = new Vector(0.0, 0.0, 0.0);
            Vector axesVelocity = new Vector(0.0, 1.0, 0.0);
            const double axesMass = 1.0;
            EulerRigidBody axesRigidBody = new EulerRigidBody(
                initialAxesLocation, axesVelocity, axesMass);
            Axes axes = new Axes(axesRigidBody);

            Vector initialLocation = new Vector(20.0, 0.0, 0.0);
            Vector velocity = new Vector(2.0, 10.0, 0.0);
            const double mass = 1.0;
            EulerRigidBody eulerRigidBody =
                new EulerRigidBody(initialLocation, velocity, mass);
            Vector force = new Vector(0.0, -1.0, 0.0);
            eulerRigidBody.ApplyForce(force);
            Sphere sphere = new Sphere(eulerRigidBody, 5.0, new Colour(0.0f, 0.0f, 1.0f));

            rigidBodies = new List<EulerRigidBody>(2);
            rigidBodies.Add(eulerRigidBody);
            rigidBodies.Add(axesRigidBody);

            drawableObjects = new List<IDrawable>(2);
            drawableObjects.Add(axes);
            drawableObjects.Add(sphere);
        }

        /// <summary>
        /// Updates all of the objects in the scene with the given time step.
        /// </summary>
        /// <param name="deltaTime">The time step, in seconds.</param>
        public void Update(double deltaTime)
        {
            foreach (EulerRigidBody rigidBody in this.rigidBodies)
            {
                rigidBody.Update(deltaTime);
            }
        }

        /// <summary>
        /// This should return an array containing 4 entries - the parameters
        ///  to pass into Gl.glrotated (i.e. angle in degrees, then the 3
        ///  values specifying the rotation vector.
        /// If null is returned (or an array of any other size), then no rotation
        ///  occurs.
        /// </summary>
        /// <remarks>
        /// A nasty hack! This will be removed once we include a camera class.
        /// If this returns non-null, then the scene will be rotated.
        /// </remarks>
        public double[] CameraRotation
        {
            get
            {
                return null;
            }
        }

        #endregion IScene Implementation

        #region Private Member Variables

        private List<EulerRigidBody> rigidBodies = null;
        private List<IDrawable> drawableObjects = null;

        #endregion Private Member Variables
    }
}
